namespace IntConcept.Graph
{
using System.Collections.Generic;

public struct Pair<T,U>
{
    public Pair(T t, U u)
    {
        first = t;
        second = u;
    }
    public T first;
    public U second;
}

public class StaticGraph: IGraph
{
    int _ec,_vc;
    int[][] _vtab;
    int[] _etab;

    public StaticGraph(int n, Pair<int, int>[] edges)
    {
        _vc = n;
        _ec = edges.Length;
        _vtab = new int[_vc][];
        _etab = new int[_ec];

        //table with needed sizes of outgoing edges
        int[] tab = new int[_vc];

        for(int i=0;i<_ec;i++)
            tab[edges[i].first]++;
        for(int i=0;i<_vc;i++)
        {
            _vtab[i] = new int[tab[i]];
            tab[i] = 0;
        }

        for(int i=0;i<_ec;i++)
        {
            _etab[i] = edges[i].second;
            _vtab[edges[i].first][tab[edges[i].first]++] = i;
        }
    }
    public int verticesCount {get{return _vc;}}
    public int edgesCount {get{return _ec;}}
    public int highestVertexId {get{return _vc-1;}}
    public int highestEdgeId {get{return _ec-1;}}
    public IEnumerable<EdgeFullInfo> edges{get
    {
        for(int i=0;i<_vc;i++)
            foreach(int e in _vtab[i])
                yield return new EdgeFullInfo(i,_etab[e],e);
    }}

    public IEnumerable<int> vertices{get{
        for(int i=0;i<_vc;i++)
            yield return i;
    }}
    public IEnumerable<EdgeInfo> outgoing(int v)
    {
        foreach(int e in _vtab[v])
            yield return new EdgeInfo(_etab[e],e);
    }
}
}
